package com.zzyweb.rentalcarsys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzyweb.rentalcarsys.entity.Car;
import com.zzyweb.rentalcarsys.entity.RentalOrder;
import com.zzyweb.rentalcarsys.entity.UserAccount;
import com.zzyweb.rentalcarsys.mapper.CarMapper;
import com.zzyweb.rentalcarsys.mapper.OrderMapper;
import com.zzyweb.rentalcarsys.mapper.UserAccountMapper;
import com.zzyweb.rentalcarsys.service.OrderService;
import com.zzyweb.rentalcarsys.utils.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhiyi
 * @date 10/9/25
 **/
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    CarMapper carMapper;
    @Autowired
    UserAccountMapper userAccountMapper;
    @Override
    @Transactional
    public RentalOrder addOrder(RentalOrder order) {


        QueryWrapper<Car> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("car_id", order.getCarId());
        Car car = carMapper.selectOne(queryWrapper);
        car.setState(1);
        carMapper.updateById(car);
        BigDecimal totalCost = car.getRentalRate().multiply(BigDecimal.valueOf(ChronoUnit.DAYS.between(order.getBeginDate(),order.getEndDate())+1));
        order.setTotalCost(totalCost);
        orderMapper.insert(order);
        return order;
    }

    @Override
    public void modifyOrder(RentalOrder order) {
        QueryWrapper<Car> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("car_id", order.getCarId());
        Car car = carMapper.selectOne(queryWrapper);
        car.setState(1);
        carMapper.updateById(car);
        BigDecimal totalCost = car.getRentalRate().multiply(BigDecimal.valueOf(ChronoUnit.DAYS.between(order.getBeginDate(),order.getEndDate())+1));
        order.setTotalCost(totalCost);
        orderMapper.updateById(order);
    }

    @Override
    public PageResult<RentalOrder> getOrdersByConditions(Long currentPage, Long pageSize, RentalOrder order) {
        Page<RentalOrder> page = new Page<>(currentPage,pageSize);
        List<RentalOrder> orders = null;
        List<Car> cars = null;
        Long[] carIds = null;
        if (order == null) {
            orders = orderMapper.selectList(page,null);
        } else {
            if (order.getUserAccount() != null && (order.getUserAccount().getId() != null || StringUtils.hasText(order.getUserAccount().getUsername())) ) {
                System.out.println("传入的用户信息是"+order.getUserAccount());
                QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq(StringUtils.hasText(order.getUserAccount().getUsername()),"username", order.getUserAccount().getUsername())
                        .eq(order.getUserAccount().getId()!=null,"id",order.getUserAccount().getId());
                List<UserAccount> userAccounts = userAccountMapper.selectList(queryWrapper);
                UserAccount userAccount = userAccountMapper.selectOne(queryWrapper);
                order.setUserId(userAccount.getId());
            }
            if (order.getCar() != null) {
                QueryWrapper<Car> queryWrapper = new QueryWrapper<>();
                Car car = order.getCar();
                queryWrapper.eq(StringUtils.hasText(car.getCarMake()),"car_make",car.getCarMake())
                        .eq(StringUtils.hasText(car.getCarModel()),"car_model",car.getCarModel())
                        .eq(StringUtils.hasText(car.getCarPlateNumber()),"car_plate_number",car.getCarPlateNumber());
                cars = carMapper.selectList(queryWrapper);
            }
            if (!cars.isEmpty()) {
                carIds = new Long[cars.size()];
                for (Car car : cars) {
                    carIds[cars.indexOf(car)] = car.getCarId();
                }
            }

            QueryWrapper<RentalOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.like(order.getOrderId() != null, "order_id", order.getOrderId())
                    .like(order.getUserId() != null, "user_id", order.getUserId())
                    .in(carIds.length != 0, "car_id", carIds)
                    .gt(order.getBeginDate()!=null, "begin_date", order.getBeginDate())
                    .lt(order.getEndDate()!=null,"end_date",order.getEndDate())
                    .eq(order.getState()!=null,"state",order.getState());
            orders = orderMapper.selectList(queryWrapper);
        }
        for (RentalOrder rentalOrder : orders) {
            Car car = carMapper.selectById(rentalOrder.getCarId());
            UserAccount userAccount = userAccountMapper.selectById(rentalOrder.getUserId());
            rentalOrder.setUserAccount(userAccount);
            rentalOrder.setCar(car);
        }
        PageResult<RentalOrder> pageResult = new PageResult<>(page.getCurrent(),page.getSize(),page.getTotal(),orders);
        return pageResult;
    }

    @Override
    @Transactional
    public void deleteOrder(String orderId) {

        //第一步拿到订单-拿到车辆 修改车辆状态
        RentalOrder order = orderMapper.selectById(Long.parseLong(orderId));
        QueryWrapper<Car> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("car_id", order.getCarId());
        Car car = carMapper.selectOne(queryWrapper);
        car.setState(0);
        carMapper.updateById(car);
        //删除订单
        orderMapper.deleteById(Long.parseLong(orderId));
    }

    @Override
    public PageResult<RentalOrder> getOrdersByUserId(String userId, Long currentPage, Long pageSize) {

        Page<RentalOrder> page = new Page<>(currentPage,pageSize);
        QueryWrapper<RentalOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.hasText(userId), "user_id", userId);
        queryWrapper.orderByDesc("order_id");
        List<RentalOrder> orders = orderMapper.selectList(page,queryWrapper);
        for (RentalOrder rentalOrder : orders) {
            Car car = carMapper.selectById(rentalOrder.getCarId());
            UserAccount userAccount = userAccountMapper.selectById(rentalOrder.getUserId());
            rentalOrder.setUserAccount(userAccount);
            rentalOrder.setCar(car);
        }
        return new PageResult<>(page.getCurrent(),page.getSize(),page.getTotal(),orders);
    }

    @Override
    public void cancelOrder(RentalOrder order) {
        Car car = carMapper.selectById(order.getCarId());
        car.setState(0);
        carMapper.updateById(car);
        order.setState(4);
        orderMapper.updateById(order);
    }

    @Override
    public RentalOrder returnCar(RentalOrder order) {
        Car car = carMapper.selectById(order.getCarId());
        car.setState(0);
        carMapper.updateById(car);
        order.setState(3);
        if (order.getEndDate().compareTo(LocalDate.now()) == 0){
            orderMapper.updateById(order);
        } else {
            BigDecimal totalCost = car.getRentalRate().multiply(BigDecimal.valueOf(ChronoUnit.DAYS.between(order.getBeginDate(), LocalDate.now())+1));
            order.setTotalCost(totalCost);
            order.setEndDate(LocalDate.now());
            orderMapper.updateById(order);
        }
        return order;
    }

    @Override
    public PageResult<RentalOrder> getAllOrders(Long currentPage, Long pageSize) {
        Page<RentalOrder> page = new Page<>(currentPage,pageSize);
        QueryWrapper<RentalOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("order_id");
        List<RentalOrder> orders = orderMapper.selectList(page,queryWrapper);
        for (RentalOrder rentalOrder : orders) {
            Car car = carMapper.selectById(rentalOrder.getCarId());
            UserAccount userAccount = userAccountMapper.selectById(rentalOrder.getUserId());
            rentalOrder.setUserAccount(userAccount);
            rentalOrder.setCar(car);
            if ((ChronoUnit.DAYS.between(rentalOrder.getBeginDate(),LocalDate.now()) >=2) && rentalOrder.getState().equals(1)) {
                rentalOrder.setState(4);
                orderMapper.updateById(rentalOrder);
                car.setState(0);
                carMapper.updateById(car);
            }
        }
        return new PageResult<>(page.getCurrent(), page.getSize(),page.getTotal(), orders);
    }

    @Override
    public RentalOrder reviewOrder(RentalOrder order) {
        Car car = carMapper.selectById(order.getCarId());
        car.setState(1);
        if (order.getBeginDate().isBefore(LocalDate.now())) {
            long between = ChronoUnit.DAYS.between(order.getBeginDate(), order.getEndDate()) + 1;
            BigDecimal totalCost = car.getRentalRate().multiply(BigDecimal.valueOf(between ));
            order.setTotalCost(totalCost);
            order.setBeginDate(LocalDate.now());
            order.setEndDate(ChronoUnit.DAYS.addTo(LocalDate.now(),between));
        }
        order.setState(2);
        orderMapper.updateById(order);
        return order;
    }
}
